﻿namespace LxCore
{
    public struct PhiCDU
    {
        public double phiC;
        public double phiD_phiC;
        public double phiC_phiU;
        public PhiCDU(double phiC, double phiD, double phiD_phiU)
        {
            this.phiC = phiC;
            this.phiD_phiC = phiD - phiC;
            this.phiC_phiU = (phiD_phiU - phiD_phiC);
        }
        public double Get_phiU() { return phiC - phiC_phiU; }
        public (double fC, double fD, double fConst) CalFactor_FOU()
        {
            return (1, 0, 0);
        }
        public (double fC, double fD, double fConst) CalFactor_SOU(double gCf)
        {
            return (1 + gCf, 0, -gCf * Get_phiU());
        }
        public (double fC, double fD, double fConst) CalFactor_CD_DC(double gCf)
        {
            return (1, 0, gCf * phiD_phiC);
        }
        public (double fC, double fD, double fConst) CalFactor_SOU_DC(double gCf)
        {
            return (1, 0, gCf * phiC_phiU);//注意，r*phiD_phiC即为phiC_phiU
        }
        public (double fC, double fD, double fConst) CalFactor_DownWind()
        {
            return (1, 0, phiD_phiC);
        }
        public (double fC, double fD, double fConst) CalFactor_SOU_CD_DC(double gCf)
        {
            switch (double.IsNegative(phiC_phiU), double.IsNegative(phiD_phiC))
            {
                case (true, false)://r<0
                case (false, true)://r<0
                    return (1, 0, 0);
                case (false, false)://增
                    return (phiC_phiU < phiD_phiC) ? CalFactor_SOU_DC(gCf) : CalFactor_CD_DC(gCf);
                case (true, true):
                    return (phiC_phiU > phiD_phiC) ? CalFactor_SOU_DC(gCf) : CalFactor_CD_DC(gCf);
            }
        }
        public (double fC, double fD, double fConst) CalFactor_OSHER_DC(double gCf)
        {
            switch (double.IsNegative(phiC_phiU), double.IsNegative(phiD_phiC))
            {
                case (true, false)://r<0
                case (false, true)://r<0
                    return (1, 0, 0);
                case (false, false)://增
                    return (phiC_phiU * gCf < phiD_phiC) ? CalFactor_SOU_DC(gCf) : CalFactor_DownWind();
                case (true, true):
                    return (phiC_phiU * gCf > phiD_phiC) ? CalFactor_SOU_DC(gCf) : CalFactor_DownWind();
            }
        }
        public (double fC, double fD, double fConst) CalFactor_MUSCL_DC(double gCf)
        {
            switch (double.IsNegative(phiC_phiU), double.IsNegative(phiD_phiC))
            {
                case (true, false)://r<0
                case (false, true)://r<0
                    return (1, 0, 0);
                case (false, false)://增
                    if (phiC_phiU * 3 < phiD_phiC)
                    {
                        return (1, 0, 2 * gCf * phiC_phiU);//二阶迎风的两倍
                    }
                    else if (phiC_phiU * gCf < phiD_phiC * (2 - gCf))
                    {
                        return (1, 0, 0.5 * gCf * (phiD_phiC + phiC_phiU));
                    }
                    else
                    {
                        return CalFactor_DownWind();
                    }
                case (true, true):
                    if (phiC_phiU * 3 > phiD_phiC)
                    {
                        return (1, 0, 2 * gCf * phiC_phiU);//二阶迎风的两倍
                    }
                    else if (phiC_phiU * gCf > phiD_phiC * (2 - gCf))
                    {
                        return (1, 0, 0.5 * gCf * (phiD_phiC + phiC_phiU));
                    }
                    else
                    {
                        return CalFactor_DownWind();
                    }
            }
        }
        //非DC格式的在SIMPLE算法中可能存在波动不收敛问题
        public (double fC, double fD, double fConst) CalFactor_OSHER(double gCf)
        {
            switch (double.IsNegative(phiC_phiU), double.IsNegative(phiD_phiC))
            {
                case (true, false)://r<0
                case (false, true)://r<0
                    return (1, 0, 0);
                case (false, false)://增
                    return (phiC_phiU * gCf < phiD_phiC) ? CalFactor_SOU(gCf) : CalFactor_DownWind();
                case (true, true):
                    return (phiC_phiU * gCf > phiD_phiC) ? CalFactor_SOU(gCf) : CalFactor_DownWind();
            }
        }
        public (double fC, double fD, double fConst) CalFactor_MUSCL(double gCf)
        {
            switch (double.IsNegative(phiC_phiU), double.IsNegative(phiD_phiC))
            {
                case (true, false)://r<0
                case (false, true)://r<0
                    return (1, 0, 0);
                case (false, false)://增
                    if (phiC_phiU * 3 < phiD_phiC)
                    {
                        gCf *= 2;
                        return (1 + gCf, 0, -gCf * Get_phiU()); ;//二阶迎风的两倍
                    }
                    else if (phiC_phiU * gCf < phiD_phiC * (2 - gCf))
                    {
                        gCf *= 0.5;
                        return (1, gCf, -gCf * Get_phiU());
                    }
                    else
                    {
                        return CalFactor_DownWind();
                    }
                case (true, true):
                    if (phiC_phiU * 3 > phiD_phiC)
                    {
                        gCf *= 2;
                        return (1 + gCf, 0, -gCf * Get_phiU()); ;//二阶迎风的两倍
                    }
                    else if (phiC_phiU * gCf > phiD_phiC * (2 - gCf))
                    {
                        gCf *= 0.5;
                        return (1, gCf, -gCf * Get_phiU());
                    }
                    else
                    {
                        return CalFactor_DownWind();
                    }
            }
        }
    }
}
